#ifndef VARIABLE_H
#define VARIABLE_H

/* $Id: variable.h,v 1.10 1997/01/21 19:17:11 dar Exp $ */

/************************************************************************
** Module:	Variable
** Description:	This module implements the Variable abstraction.  A
**	Variable consists of a name, a type, a reference class, and
**	some flags, e.g. 'optional', 'variable'.  It is used to represent
**	entity attributes, variables, and formal parameters.
** Constants:
**	VARIABLE_NULL	- the null variable
**
************************************************************************/

/*
 * This code was developed with the support of the United States Government,
 * and is not subject to copyright.
 *
 * $Log: variable.h,v $
 * Revision 1.10  1997/01/21 19:17:11  dar
 * made C++ compatible
 *
 * Revision 1.9  1995/04/05  14:58:31  clark
 * CADDETC preval
 *
 * Revision 1.8  1994/05/11  19:51:05  libes
 * numerous fixes
 *
 * Revision 1.7  1993/10/15  18:48:24  libes
 * CADDETC certified
 *
 * Revision 1.6  1993/03/19  20:42:36  libes
 * fixed get_inverse macro
 *
 * Revision 1.5  1993/02/16  03:27:55  libes
 * added flag for simplifying detection of parameters from other vars
 *
 * Revision 1.4  1993/01/19  22:15:13  libes
 * *** empty log message ***
 *
 * Revision 1.3  1992/08/18  17:12:41  libes
 * rm'd extraneous error messages
 *
 * Revision 1.2  1992/06/08  18:06:24  libes
 * prettied up interface to print_objects_when_running
 */

/*************/
/* constants */
/*************/

#define VARIABLE_NULL		(Variable)0

/*****************/
/* packages used */
/*****************/

#include "expbasic.h"	/* get basic definitions */
#include "symbol.h"       

/************/
/* typedefs */
/************/

typedef struct Variable_ *Variable;

/****************/
/* modules used */
/****************/
       
#include "type.h"
#include "expr.h"

/***************************/
/* hidden type definitions */
/***************************/

struct Variable_ {
	/* Symbol is inside of 'name' below */
	Expression name;
	Type type;
	Expression initializer;	/* or 'derived' */
	int		offset;

	struct {
		int optional	:1;	/* OPTIONAL keyword */
		int var		:1;	/* VAR keyword */
		int constant	:1;	/* from CONSTANT...END_CONSTANT */
		int unique	:1;	/* appears in UNIQUE list */
		int parameter	:1;	/* is a formal parameter */
		int attribute	:1;	/* is an attribute (rule parameters */
					/* are marked this way, too) */
	} flags;

#define query_symbol inverse_symbol
	Symbol *	inverse_symbol;	/* entity symbol */
	Variable 	inverse_attribute;	/* attribute related by */
				/* inverse relationship */
};

/********************/
/* global variables */
/********************/

#ifdef VARIABLE_C
#include "defstart.h"
#else
#include "decstart.h"
#endif    /*  VARIABLE_C  */

GLOBAL struct freelist_head VAR_fl;

#include "de_end.h"

/******************************/
/* macro function definitions */
/******************************/

#define VAR_new()	(struct Variable_ *)MEM_new(&VAR_fl)
#define VAR_destroy(x)	MEM_destroy(&VAR_fl,(Freelist *)(Generic)x)

#define VARget_name(v)			((v)->name)
#define VARput_name(v,n)		((v)->name = (n))
#define VARput_offset(v,off)		((v)->offset = (off))
#define VARget_offset(v)		((v)->offset)

#define VARget_initializer(v)		((v)->initializer)
#define VARget_type(v)			((v)->type)
#define VARget_optional(v)		((v)->flags.optional)
#define VARget_unique(v)		((v)->flags.unique)

#define VARis_derived(v)		((v)->initializer != 0)
#define VARget_inverse(v)		((v)->inverse_attribute)
/* for backwards compatibility */
#define VARget_derived		VARis_derived

/***********************/
/* function prototypes */
/***********************/

extern Variable VARcreate PROTO((Expression, Type));
extern void VARinitialize PROTO((void));
extern char *VARget_simple_name PROTO((Variable));

#if 0
extern void		VARput_type PROTO((Variable *, Type));
extern void		VARput_initializer PROTO((Variable *, Expression));
extern void		VARput_derived PROTO((Variable *, Boolean));
extern void		VARput_optional PROTO((Variable *, Boolean));
extern void		VARput_variable PROTO((Variable *, Boolean));
extern void		VARput_reference PROTO((Variable *,Expression));
/*Mextern void		VARput_offset PROTO((Variable *, int));*/
extern void		VARput_inverse PROTO((Variable *,Symbol *));
/*M extern Type		VARget_type PROTO((Variable *));*/
/*Mextern Boolean		VARget_derived PROTO((Variable *));*/
extern Boolean		VARget_optional PROTO((Variable *));
extern Boolean		VARget_variable PROTO((Variable *));
extern Expression	VARget_reference PROTO((Variable *));
/*Mextern int		VARget_offset PROTO((Variable *));*/
#endif /*0*/

/********************/
/* inline functions */
/********************/

#if supports_inline_functions || defined(VARIABLE_C)

#endif /* supports_inline_functions || defined(VARIABLE_C) */

#endif    /*  VARIABLE_H  */
